#pragma once

#include "space\types.h"
#include "space\i_manager.h"
#include "space\collection.h"

#include <list>
#include <vector>
#include <concurrent_unordered_map.h>

namespace space {
	namespace managers {

		class entity_manager :
			public i_manager
		{
		public:
			result on_post_update(i_engine_ptr, float);
			result on_pre_update(i_engine_ptr, float);
			result on_update(i_engine_ptr, float);

			result initialize(i_engine_ptr);
			result release(i_engine_ptr);

			entity_ptr create(void);
			entity_ptr create(const std::string &name);
			result destroy(entity_ptr);

			result assign_tag(const std::string &, entity_ptr);
			result remove_tag(const std::string &, entity_ptr);

			result find_by_tag(const std::string &, std::vector<entity_ptr> &) const;

			entity_ptr find_by_name(const std::string name) const;
			entity_ptr find_by_id(const u_int64 name) const;

			entity_manager();
			~entity_manager();
		
			result tags(std::vector<std::string> &) const;
			collection<entity_ptr> & entities(void) { return _entities; }
		protected:
			collection<entity_ptr> _entities;
			concurrency::concurrent_unordered_map<std::string, std::list<entity_ptr> > _tags;
		};
		typedef shared_ptr<entity_manager> entity_manager_ptr;
	};
};